package com.mls.guardian.executor.master;

import com.mls.guardian.appst.chain.TaskResult;
import com.mls.guardian.common.RemoteUtil;
import com.mls.guardian.container.MasterContainer;
import com.mls.guardian.dataobj.ServerProcessInfo;
import com.mls.guardian.em.ContainerRole;
import com.mls.guardian.protocol.RemoteBody;
import com.mls.guardian.protocol.RemoteCommand;
import com.mls.guardian.protocol.body.AppRestartBody;
import com.mls.guardian.remoting.executor.RemoteExecutor;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by root on 15-12-7.
 */
public class UpgradeExecutor implements RemoteExecutor {
    private static final Logger log = LoggerFactory.getLogger(RestartAppExecutor.class);
    private MasterContainer container;
    private Lock restartLock = new ReentrantLock();

    public UpgradeExecutor(MasterContainer container) {
        this.container = container;
    }

    @Override
    public RemoteBody execute(ChannelHandlerContext ctx, RemoteCommand request) throws Exception {
        AppRestartBody response = new AppRestartBody();

        if (restartLock.tryLock()) {
            try {
                List<Future<RemoteBody>> futures = new ArrayList<>();

                AppRestartBody appRestart = (AppRestartBody) request.getRemoteBody();

                if (appRestart.getVersionTag() == null || appRestart.getVersionTag().length() == 0) {
                    //appRestart.setErrorContent("VersionTag未指定");
                    final String DATE_FORMAT = "yyyy-MM-dd_HH-mm-ss-SSS";
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
                    String versionTag = simpleDateFormat.format(new Date(System.currentTimeMillis()));
                    appRestart.setVersionTag(versionTag);

                    request.setRemoteBody(appRestart);
                    response.setVersionTag(versionTag);
                } else {
                    response.setVersionTag(appRestart.getVersionTag());
                }


                //SLAVE所有节点
                List<String> listAddr = new ArrayList<String>();
                Map clients = this.container.getClientDispatch().getClient();
                Iterator iterator = clients.keySet().iterator();
                while (iterator.hasNext()) {
                    listAddr.add((String) iterator.next());
                }

                //先执行Slave
                log.info("----Slave开始重启Guardian----" + listAddr.toString());
                container.getClientDispatch().sendRequestToClientOneWay(request, listAddr);

                //再执行Master
                log.info("----Master开始重启Guardian[{}]----", RemoteUtil.getLocalHostIP());
                TaskResult taskResult = container.getAppController().upgrade(ContainerRole.MASTER, appRestart.getVersionTag());
                response.setSuc(taskResult.isSuc());
                log.info("master 重启Guardian结束 返回");
            } finally {
                restartLock.unlock();
            }
        } else {
            response.setSuc(false);
            response.setErrorContent("正在执行restart Guardian请等待完成后再发送请求");
        }


        return response;
    }
}
